'''
Created on 09.08.2010

@author: Valiuh Anton - valiuh@gmail.com
'''


import Image
from VideoCapture import Device
import ImageDraw



class Find_FaceObj(object):
	'''
	This class using for find face in input RGB image.
		Then coordinates which was found in image by 
		color histograms will be used to draw an ellipse 
		around face in input RGB image. 
		
		InitMatrixRGB() - Initialization matrix of tuples (r,g,b) 
			for work width RGB image.
			
		InitMatrixBin() - Initialization binary matrix for work 
			width grey scale image (binary image).
			
		Image_To_Matrix() - Converting some image into marix for perform 
			more fast image operations (calculations).	
			
		Matrix_To_Image() - Converting marix into some image for savind 
			results of image operations in some format (usualy jpeg).
			
		RGB2YCbCr() - Convert one pixel from RGB to YCbCr.
		
		YCbCr2GREY() - Convert one "pixel" (matrix element) from YCbCr to 
			grey skin color model.      
			
		RGBMat_To_CbCrMat() - Convert RGB matrix to YCbCr.
		
		CbCrMat_To_BinMat() - Convert YCbCr matrix to binary matrix                                   
		
		CalcHists_Find_Face() - procedure for calculation X(width) 
			and Y(height) distributions of white component in 
			input grey scale image. After alculation X(width) 
			and Y(height) distributions alculation distributions,
			begin finding center of ellipse - max value in X(width) 
			and Y(height) distributions. And than it draw an ellipse 
			around face in input RGB image. 
		width_hist - X(width) distributions of white component
		height_hist - Y(height) distributions of white component 
	'''
#=================================================================
	def __init__(self,width,height):
		'''
			Constructor
		'''
		self.width=width
		self.height=height
#=================================================================
	def InitMatrixRGB(self,width,height):
		'''
			Initialization matrix of tuples (r,g,b) for work width 
			RGB image.
		'''
		rgb = [0,0,0]
		matrix = [[rgb for i in range(height)] for j in range(width)]
		return matrix
#=================================================================    
	def InitMatrixBin(self,width,height):
		'''
			Initialization binary matrix for work width 
			grey scale image (binary image).
		'''	
		rgb = 0
		matrix = [[rgb for i in range(height)] for j in range(width)]
		return matrix
#=================================================================    
	def Image_To_Matrix(self,matrix,image):
		'''
			Converting some image into marix for perform more fast
			image operations (calculations).			
		'''
		width, height = image.size
	
		for i in range(height):
			for j in range (width):
				rgb = image.getpixel((j,i)) 
				matrix[j][i] = rgb
			
		return matrix 
#=================================================================    
	def Matrix_To_Image(self,matrix,image):
		'''
			Converting marix into some image for savind results of
			image operations in some format (usualy jpeg).			
		'''
		width, height = image.size
		for i in range(height):
			for j in range (width):
				rgb = matrix[j][i]
				image.putpixel((j,i),rgb)
		return image

#=================================================================
	def RGB2YCbCr (self,rgb):
		'''
			Convert one pixel from RGB to YCbCr                                   
		'''        
		cbcr = [0,0,0]
		cbcr[0] =  int(0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2]) #Y
		cbcr[1] =  int((rgb[2] - cbcr[0])*0.565 + 128) #Cb
		cbcr[2] =  int((rgb[0] - cbcr[0])*0.713 + 128) #Cr
		return cbcr
#=================================================================
	def YCbCr2GREY (self,rgb):
		'''
			Convert one "pixel" (matrix element) from YCbCr to grey 
			skin color model                                   
		'''        

		if ((rgb[1]>90)&(rgb[1]<140))&((rgb[2]>90)&(rgb[2]<140)):
			grey = 0
		else:
			grey = 255
		return grey    
#=================================================================
	def RGBMat_To_CbCrMat(self,rgb,cbcr):
		'''
			Convert RGB matrix to YCbCr                                   
		'''
		for i in range(self.height):
			for j in range (self.width):
				cbcr[j][i] = self.RGB2YCbCr(rgb[j][i])
		return cbcr
#=================================================================
	def CbCrMat_To_BinMat(self,cbcr,bin):
		'''
			Convert YCbCr matrix to binary matrix                                   
		'''
		for i in range(self.height):
			for j in range (self.width):
				bin[j][i] = self.YCbCr2GREY(cbcr[j][i])
			
		return bin 
#==================================================================   
	def CalcHists_Find_Face(self,bin,image):
		'''
			Calculation X(width) and Y(height) distributions 
			of white component in input grey scale image.
			And than it draw an ellipse around face in 
			input RGB image 
		'''
		width_hist=[]
		height_hist=[]
		count = 0
		for i in range(self.height):
			for j in range (self.width):
				if bin[j][i]==255:
					count=count+1
			height_hist.append(count)
			count = 0

		count = 0
		for i in range(self.width):
			for j in range (self.height):
				if bin[i][j]==255:
					count=count+1
			width_hist.append(count)
			count = 0 
	
		y = height_hist.index(max(height_hist))
		x = width_hist.index(max(width_hist))
	
		draw = ImageDraw.Draw(image)
		draw.ellipse((x-20,y-20,x+20,y+20), None, "blue")
				
		image.save('C:\\Python26\\work.jpg',"JPEG")
		return [x,y]
	
		